import { MenuVoInfo } from '#/entity';
import { useTheme } from '@/store/settingsStore';
import { useUserId } from '@/store/userStore';
import { EditModal } from '@ycx/ui';
import { App, Form, Input, Select, TreeDataNode } from 'antd';
import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react';
import PermissionTree from './PermissionTree';
import { useMutation, useQuery } from '@tanstack/react-query';
import RoleServices from '@/api/services/roleServices';
import { useCatch } from '@/hooks';

interface FormInstance {
  roleName: string;
  roleDesc: string;
  permissionList: string[];
}

export interface EditRoleModalRef {
  open: (roleId?: number) => void;
}

type Props = {
  allPermissions: MenuVoInfo[];
  onSuccess: () => void;
};

const EditRoleModal = forwardRef<EditRoleModalRef, Props>(({ allPermissions, onSuccess }, ref) => {
  const { message } = App.useApp();
  const theme = useTheme();
  const catchFn = useCatch();
  const [open, setOpen] = useState(false);
  const [roleId, setRoleId] = useState(0);
  const [form] = Form.useForm<FormInstance>();
  const userId = useUserId();

  const roleNameOptions = useMemo(() => {
    if (userId === 1) return ['新疆交投公路养护集团'].map((i) => ({ label: i, value: i }));
    return ['项目经理', '养护负责人', '技术员'].map((i) => ({ label: i, value: i }));
  }, [userId]);

  useImperativeHandle(ref, () => ({
    open(roleId?: number) {
      setOpen(true);
      setRoleId(roleId ?? 0);
    },
  }));

  const close = () => {
    setOpen(false);
    setRoleId(0);
    form.resetFields();
  };

  const { data: roleDetail } = useQuery({
    queryKey: ['role-detail', roleId],
    queryFn: () => catchFn(() => RoleServices.getRoleDetail(roleId)),
    select: ({ data }) => data,
    enabled: !!roleId,
    staleTime: 0,
  });

  useEffect(() => {
    form.setFieldsValue({
      roleName: roleDetail?.roleName,
      roleDesc: roleDetail?.roleDesc,
      permissionList: roleDetail?.menuVoList.map((i) => i.menuPath) || [],
    });
  }, [roleDetail]);

  const { mutate: saveRole } = useMutation({
    mutationFn: RoleServices.saveRole,
    async onSuccess({ data }) {
      const formData = form.getFieldsValue();

      assignMenu([
        {
          roleId: data.id,
          menuPaths: [...formData.permissionList],
          areaCode: '',
        },
      ]);
    },
    onError(error) {
      message.error(error.message);
    },
  });

  const { mutate: updateRole } = useMutation({
    mutationFn: RoleServices.updateRole,
    async onSuccess() {
      const formData = form.getFieldsValue();

      assignMenu([
        {
          roleId,
          menuPaths: [...formData.permissionList],
          areaCode: '',
        },
      ]);
    },
    onError(error) {
      message.error(error.message);
    },
  });

  const { mutate: assignMenu } = useMutation({
    mutationFn: RoleServices.assignMenu,
    async onSuccess() {
      message.success(`${!roleId ? '新建' : '编辑'}角色成功`);
      close();
      onSuccess();
    },
    onError(error) {
      message.error(error.message);
    },
  });

  const onSubmit = async () => {
    if (!userId) return;

    await form.validateFields();

    const params = form.getFieldsValue();

    if (!params.permissionList || params.permissionList.length === 0) {
      message.warning('请勾选菜单权限');
      return;
    }

    if (!roleId) {
      saveRole({
        userId,
        roleName: params.roleName,
        roleDesc: params.roleDesc || '',
      });
    } else {
      updateRole({
        id: roleId,
        userId,
        roleName: params.roleName,
        roleDesc: params.roleDesc || '',
      });
    }
  };

  const treeData = useMemo<TreeDataNode[]>(() => {
    const recursionTree = (
      permissions: MenuVoInfo[],
      parentNode: MenuVoInfo | null,
    ): TreeDataNode[] => {
      return permissions.map((p) => {
        const node = {
          key: p.menuPath,
          title: p.menuName,
          children: p.childrenMenu ? recursionTree(p.childrenMenu, p) : [],
          parentNode,
        };

        return node;
      });
    };

    return recursionTree(allPermissions, null);
  }, [allPermissions]);

  return (
    <EditModal
      width={600}
      title={`${!roleId ? '添加' : '编辑'}角色`}
      theme={theme}
      open={open}
      onClose={close}
      onCancel={close}
      onOk={onSubmit}
      forceRender
      modalRender={(dom) => (
        <Form form={form} layout="vertical">
          {dom}
        </Form>
      )}
    >
      <Form.Item
        label="角色名称"
        name="roleName"
        rules={[{ required: true, message: '请选择角色名称' }]}
      >
        <Select allowClear placeholder="请选择角色名称" options={roleNameOptions} />
      </Form.Item>
      <Form.Item label="角色描述" name="roleDesc">
        <Input allowClear placeholder="请输入角色描述" />
      </Form.Item>
      <Form.Item label="菜单权限" name="permissionList">
        <PermissionTree treeData={treeData} />
      </Form.Item>
    </EditModal>
  );
});

export default EditRoleModal;
